package org.dtrd.modules.record.controller;

import cn.hutool.core.util.StrUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.dtrd.base.BaseController;
import org.dtrd.common.api.vo.Result;
import org.dtrd.common.aspect.annotation.AutoLog;
import org.dtrd.common.util.DateUtils;
import org.dtrd.config.system.Constant;
import org.dtrd.config.system.SystemState;
import org.dtrd.modules.base.service.BaseCommonService;
import org.dtrd.modules.record.entity.bean.BloodBean;
import org.dtrd.modules.record.entity.bean.BloodPressureChartBean;
import org.dtrd.modules.record.entity.bean.BloodPressureDailyInfo;
import org.dtrd.modules.record.entity.bean.PeriodBloodPressure;
import org.dtrd.modules.record.entity.request.TimePeriodRequest;
import org.dtrd.modules.record.service.IDtrdEntRdUplowRecordService;
import org.dtrd.modules.record.service.impl.BloodPressureRecordServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.text.ParseException;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static org.dtrd.common.constant.CommonConstant.OPERATE_TYPE_QUERY;
import static org.dtrd.common.constant.CommonConstant.OPERATE_TYPE_SAVE_OR_UPDATE;

/**
 * 血压记录
 *
 * @author 萧
 * @date:2021-10-02 5:48 下午
 **/
@Slf4j
@RestController
@RequestMapping("/101/05")
@Api(tags = "血压记录接口")
public class BloodPressureController extends BaseController {

    @Autowired
    private BloodPressureRecordServiceImpl bloodPressureRecordServiceImpl;
    @Autowired
    private BaseCommonService baseCommonService;
    @Autowired
    private IDtrdEntRdUplowRecordService dtrdEntRdUplowRecordService;

    @ApiOperation("添加血压记录/一次6条")
    @PostMapping("/1010504")
    public Result<?> saveBloodPressure(@RequestBody BloodPressureDailyInfo info) {
        // 校验 patientId 记录时间, 值空就空吧, 可以改...
        if (info.getPatientId() == null
                || info.getRecordTime() == null) {
            return error(SystemState.ResponseState.STATE_PARAMS_MISSING);
        }
        // 添加数据校验, 不能一个都不填
        if (info.getMorningHeartRate() == null
                && info.getMorningHigh() == null
                && info.getMorningLow() == null
                && info.getNightHeartRate() == null
                && info.getNightHigh() == null
                && info.getNightLow() == null) {
            return error(SystemState.ResponseState.STATE_PARAMS_MISSING);
        }

        String logContent = String.format("添加或修改血压记录，患者id：%d", info.getPatientId());
        baseCommonService.addLog(logContent, OPERATE_TYPE_SAVE_OR_UPDATE);
        boolean result = bloodPressureRecordServiceImpl.saveBloodPressureRecord(info);
        return result ? Result.OK() : error(SystemState.ResponseState.STATE_OPERATION_FAILURE);
    }

    @ApiOperation("添加血压记录/按照类型")
    @PostMapping("/1010507")
    public Result<?> saveOrUpdatePressure(@RequestBody BloodBean bloodInfo) {
        // 患者id 记录日期 时间段类型 不能为空 高压/低压/心率不能同时为空
        if (StrUtil.isBlank(bloodInfo.getTime())
                || bloodInfo.getPatientId() == null
                || bloodInfo.getRecordType() == null
                || (bloodInfo.getLow() == null || bloodInfo.getHigh() == null || bloodInfo.getHeart() == null)) {
            return error(SystemState.ResponseState.STATE_PARAMS_MISSING);
        }
        // 判断传入的类型是否正确
        Integer bloodInfoType = bloodInfo.getRecordType();
        Constant.BloodPressureRecordType bloodPressureRecordType = Constant.BloodPressureRecordType.valueOf(bloodInfoType);
        if (bloodPressureRecordType == null) {
            return error(SystemState.ResponseState.STATE_PARAMS_ERROR);
        }
        boolean result = bloodPressureRecordServiceImpl.saveBloodPressureRecord(bloodInfo);
        String logContent = String.format("添加血压记录，患者id：%d，添加类型: %s", bloodInfo.getPatientId(), bloodInfo.getRecordType());
        baseCommonService.addLog(logContent, OPERATE_TYPE_SAVE_OR_UPDATE);
        return result ? Result.OK() : error(SystemState.ResponseState.STATE_OPERATION_FAILURE);
    }


    @ApiOperation("获取血压曲线-1010501")
    @PostMapping("/1010501")
    @AutoLog(value = "获取血压曲线", operateType = OPERATE_TYPE_QUERY)
    public Result<?> getBloodPressureTimePeriod(@RequestBody TimePeriodRequest request) {
        if (request.getPatientId() == null) {
            return error(SystemState.ResponseState.STATE_PARAMS_MISSING);
        }
        String startDate = null;
        String endDate = null;
        String[] timePeriod = handleTimePeriod(request);
        if (timePeriod != null) {
            startDate = timePeriod[0];
            endDate = timePeriod[1];
        }
        if (startDate == null || endDate == null) {
            return error(SystemState.ResponseState.STATE_PARAMS_MISSING);
        }
        Integer patientId = request.getPatientId();
        PeriodBloodPressure record = bloodPressureRecordServiceImpl.getBloodPressureRecordsForCharts(patientId, startDate, endDate);
        return Result.OK(record);
    }

    @ApiOperation("血压记录列表-1010502")
    @PostMapping("/1010502")
    @AutoLog(value = "血压记录列表", operateType = OPERATE_TYPE_QUERY)
    public Result<?> getBloodPressureList(@RequestBody TimePeriodRequest request) {
        int patientId = getIntParam(request.getPatientId(), 0);
        if (patientId < 1) {
            return error(SystemState.ResponseState.STATE_PARAMS_MISSING);
        }
        // 为折线图返回数据 默认0不需要 1 需要
        int forChart = getIntParam(request.getForChart(), 0);
        // 为0表示按日期查询，为1表示按分页查询
        // 3 按照指定周期查询
        int type = getIntParam(request.getType(), 1);
        String startDate = null;
        String endDate = null;
        String[] timePeriod = handleTimePeriod(request);
        if (timePeriod != null) {
            startDate = timePeriod[0];
            endDate = timePeriod[1];
        }
        int page = getIntParam(request.getPage(), 0);
        int pageSize = getIntParam(request.getPageSize(), Constant.PAGESIZE);
        BloodPressureChartBean chart = null;
        List<BloodBean> list;
        if (type == 1) {
            list = bloodPressureRecordServiceImpl.getAllBloodPressureByPage(patientId, page, pageSize);
        } else {
            if (forChart == 1) {
                chart = bloodPressureRecordServiceImpl.getBloodPressureRecordsForChartsInApp(patientId, startDate, endDate);
            }
            if (type == 3) {
                list = bloodPressureRecordServiceImpl.getAllBloodPressureBetweenTimeByPage(patientId, startDate, endDate, page, pageSize);
            } else {
                list = bloodPressureRecordServiceImpl.getAllBloodPressureByDate(patientId, startDate, endDate, type == 2);
            }
        }
        Map map = new HashMap();
        float[] systolicPressure = dtrdEntRdUplowRecordService.getSystolicPressure(patientId);
        float[] diastolicPressure = dtrdEntRdUplowRecordService.getDiastolicPressure(patientId);
        map.put("highLimit", systolicPressure);
        map.put("lowLimit", diastolicPressure);
        if (chart == null) {
            map.put("noRecordTips", "暂时还没有记录哦~");
        } else {
            map.put("chart", chart);
        }
        Integer count = bloodPressureRecordServiceImpl.getBloodPressureRecordDateCount(patientId, startDate, endDate);
        if (count != null && count > 0) {
            map.put("count", count);
            map.put("totalPage", count <= pageSize || pageSize <= 0 ? 1 : setTotalPage(pageSize, count));
        }
        map.put("recordList", list);
        return Result.OK(map);
    }


    @ApiOperation("查询某个指定日期的血压记录")
    @GetMapping("/1010506")
    @AutoLog(value = "查询某个指定日期的血压记录", operateType = OPERATE_TYPE_QUERY)
    public Result<?> getBloodPressureRecord(@RequestParam Integer patientId, @RequestParam String queryDate) {
        if (isIntParamInvalid(patientId) || StrUtil.isBlank(queryDate)) {
            return error(SystemState.ResponseState.STATE_PARAMS_MISSING);
        }
        Date date;
        try {
            date = DateUtils.parseDate(queryDate, DateUtils.date_sdf.get().toPattern());
        } catch (ParseException e) {
            e.printStackTrace();
            log.error("getBloodPressureRecord.queryDate 转换失败: " + queryDate);
            return error(SystemState.ResponseState.STATE_PARAMS_ERROR);
        }
        // 补充 patientId 和 查询日期
        BloodPressureDailyInfo info = bloodPressureRecordServiceImpl.getBloodPressure(patientId, date);
        info.setPatientId(patientId);
        info.setRecordTime(queryDate);
        return Result.OK(info);
    }


    @ApiOperation("查询血压统计数据 按时段类别统计 总次数，最高、最低值、平均值、偏高、偏低、正常次数")
    @GetMapping(value = "/1010503")
    @AutoLog(value = "查询血压统计数据", operateType = OPERATE_TYPE_QUERY)
    public Result<?> getBloodPressureStatistics(@RequestParam Integer patientId,
                                                @RequestParam Integer type, @RequestParam(required = false) String startTime,
                                                @RequestParam(required = false) String endTime, @RequestParam Integer period) {
        try {
            if (patientId <= 0 || (type != 3 && StringUtils.isEmpty(startTime))) {
                return Result.error(SystemState.ResponseState.STATE_PARAMS_ERROR.getCode(), SystemState.ResponseState.STATE_PARAMS_ERROR.getMsg());
            } else {
                Map map = bloodPressureRecordServiceImpl.getBloodPressureStatistics(patientId, type, startTime, endTime, period);
                return Result.OK(map);
            }
        } catch (Exception e) {
            log.error("获取血压统计信息异常", e);
            return Result.error(SystemState.ResponseState.STATE_OPERATION_FAILURE.getCode(), SystemState.ResponseState.STATE_OPERATION_FAILURE.getMsg());
        }
    }

    @ApiOperation("血压记录列表-1010505")
    @PostMapping("/1010505")
    public Result<?> getJoinBloodPressureList(@RequestBody TimePeriodRequest request) {
        int patientId = getIntParam(request.getPatientId(), 0);
        if (patientId < 1) {
            return error(SystemState.ResponseState.STATE_PARAMS_MISSING);
        }
        int page = getIntParam(request.getPage(), 0);
        int pageSize = getIntParam(request.getPageSize(), Constant.PAGESIZE);
        Map map = new HashMap(5);
        Integer count = bloodPressureRecordServiceImpl.getBloodPressureRecordDateCount(patientId, null, null);
        if (count != null && count > 0) {
            map.put("count", count);
            map.put("totalPage", count <= pageSize || pageSize <= 0 ? 1 : count / pageSize + 1);
            List<BloodBean> list = bloodPressureRecordServiceImpl.getAllBloodPressureBetweenTimeByPage(patientId, null, null, page, pageSize);
            map.put("recordList", list);
        } else {
            map.put("noRecordTips", "暂时还没有记录哦~");
        }
        return Result.OK(map);
    }

}
